﻿using DataTransferForWCFHelper;
using ICSharpCode.SharpZipLib.Zip;
using IPRMIS_U_Contract;
using Layer;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PremisPublisher.Common
{

    /*
 
项目发布及数据结构
     * 
     * 解析 publishs.xml，并通过wcf服务发布项目
* 
* 作者：张鹏 
* 日期：2016.5
 
*/
    public class XAdditional
    {
        public string dest_path { get; set; }

        public List<AdditionalFile> Files { get; set; }

        public XAdditional(string dest_path)
        {
            this.dest_path = dest_path;
        }

        public bool DoPublish(Action<IPublish> ar_callback)
        {
            foreach (var file in Files)
            {
                file.Publish(ar_callback);
            }

            return false;
        }
    }


    public class AdditionalFile : IPublish
    {
        public string SourcePath { get; set; }
        public string TargetPath { get; set; }
        public string CharSet { get; set; }
        public string Zip { get; set; }

        public Dictionary<string, KeyValuePair<string, string>> Reps = new Dictionary<string, KeyValuePair<string, string>>();

        public AdditionalFile(string src_file, string dest_path, string zip = "0")
        {
            this.SourcePath = src_file;
            this.TargetPath = dest_path;
            this.Zip = zip;
            this.CharSet = "utf-8";
        }

        public void Publish(Action<IPublish> ar_callback)
        {
            if (!System.IO.File.Exists(SourcePath))
            {
                this.TargetPath = string.Format("{0} 不存在，请检查", SourcePath);
                ar_callback(this);
                return;
            }

            if (Reps.Count > 0) DoReplace();

            var buffer = System.IO.File.ReadAllBytes(SourcePath);

            var msg = new FileTransferMessage()
            {
                Buffer = buffer,
                Length = buffer.Length,
                FileLocation = TargetPath
            };

            var uploader = new DoPublishUpload<FileTransferMessage>();
            uploader.OnCompleted += (o, e) =>
            {
                if (msg.Msg != null)
                    this.TargetPath = msg.Msg;
                ar_callback(this);
            };
            uploader.OnProgressChanged += (o, e) => { };
            uploader.Go("0099", msg);
        }

        public bool DoReplace()
        {
            if (!System.IO.File.Exists(this.SourcePath))
            {
                return false;
            }

            //解包 替换 重新打包

            if (this.Zip.Equals("1"))
            {
                var zipTemp = AppDomain.CurrentDomain.BaseDirectory + "\\ZipTemp";
                FastZip fastZip = new FastZip();
                string fileFilter = null;

                fastZip.ExtractZip(SourcePath, zipTemp, fileFilter);

                foreach (var rep in Reps)
                {
                    var cfg_file = zipTemp + "\\" + rep.Key;
                    var f = System.IO.File.ReadAllText(cfg_file, Encoding.GetEncoding(CharSet));
                    f = f.Replace(rep.Value.Key, rep.Value.Value);
                    new System.IO.FileInfo(cfg_file).IsReadOnly = false;
                    System.IO.File.WriteAllText(cfg_file, f, Encoding.GetEncoding(CharSet));
                }

                fastZip.CreateZip(this.SourcePath, zipTemp, true, "");
            }
            else
            {
                foreach (var rep in Reps)
                {
                    string filename = System.IO.Path.Combine(this.SourcePath, rep.Key);
                    var f = System.IO.File.ReadAllText(filename , Encoding.GetEncoding(CharSet));
                    f = f.Replace(rep.Value.Key, rep.Value.Value);
                    new System.IO.FileInfo(filename).IsReadOnly = false;
                    System.IO.File.WriteAllText(filename, f, Encoding.GetEncoding(CharSet));
                }
            }

            return System.IO.File.Exists(this.SourcePath);
        }

    }

    public class XPublish
    {
        public string Source { get; set; }
        public string Target { get; set; }
        public List<RFile> Files { get; set; }
        public List<RDir> Dirs { get; set; }

        public XPublish(string src, string target)
        {
            this.Source = src;
            this.Target = target;
        }

        public bool DoPublish(Action<IPublish> ar_callback)
        {
            foreach (var dir in Dirs)
            {
                dir.Publish(ar_callback);
            }

            foreach (var file in Files)
            {
                file.Publish(ar_callback);
            }

            return false;
        }
    }

    public interface IPublish
    {
        string SourcePath { get; set; }
        string TargetPath { get; set; }
        void Publish(Action<IPublish> ar_callback);

    }

    public class RDir : IPublish
    {
        public string SourcePath { get; set; }
        public string TargetPath { get; set; }
        public bool RSA { get; set; }

        public RDir(string p, string t, string r)
        {
            this.SourcePath = p; this.RSA = Convert.ToBoolean(r);
            this.TargetPath = t;
        }

        public void Publish(Action<IPublish> ar_callback)
        {
            List<string> src_files = null;

            try
            {
                src_files = System.IO.Directory.GetFiles(SourcePath).ToList();
            }
            catch (Exception ex)
            {
                this.TargetPath = ex.Message;
                ar_callback(this);

                return;
            }

            var dest_files = new List<string>();

            if (this.RSA)//加密处理
            {
                string temp_path = System.IO.Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "temp");

                if (System.IO.Directory.Exists(temp_path))
                {
                    foreach (var item in System.IO.Directory.GetFiles(temp_path))
                    {
                        System.IO.FileInfo fi = new System.IO.FileInfo(item);
                        fi.IsReadOnly = false;
                        fi.Delete();
                    }
                }
                else System.IO.Directory.CreateDirectory(temp_path);

                var pub_inst = PublisherReader.GetInstance();

                foreach (var sfile in src_files)
                {
                    var tfile = System.IO.Path.Combine(temp_path, System.IO.Path.GetFileName(sfile));
                    System.IO.File.Copy(sfile, tfile, true);
                    pub_inst.rsa_crypt(tfile);
                    dest_files.Add(tfile);
                }

                src_files = new List<string>(dest_files);
            }

            foreach (var file in src_files)
            {
                var target_file = System.IO.Path.Combine(TargetPath, System.IO.Path.GetFileName(file));
                new RFile(file, target_file, "utf-8").Publish(ar_callback);
            }
        }
    }


    public class RFile : IPublish
    {
        public string SourcePath { get; set; }
        public string TargetPath { get; set; }
        public string CharSet { get; set; }

        public List<KeyValuePair<string, string>> Reps = new List<KeyValuePair<string, string>>();

        public RFile(string path, string t, string charset="utf-8")
        {
            this.SourcePath = path;
            this.TargetPath = t;
            this.CharSet = charset;
        }

        public bool DoReplace()
        {
            if (!System.IO.File.Exists(this.SourcePath))
            {
                return false;
            }

            var f = System.IO.File.ReadAllText(this.SourcePath, Encoding.GetEncoding(CharSet));

            foreach (var rep in Reps)
            {
                f = f.Replace(rep.Key, rep.Value);
            }

            new System.IO.FileInfo(this.SourcePath).IsReadOnly = false;

            System.IO.File.WriteAllText(this.SourcePath, f, Encoding.GetEncoding(CharSet));

            return System.IO.File.Exists(this.SourcePath);
        }

        public void Publish(Action<IPublish> ar_callback)
        {

            if (!System.IO.File.Exists(SourcePath))
            {
                this.TargetPath = string.Format("{0} 不存在，请检查", SourcePath);
                ar_callback(this);
                return;
            }

            if (Reps.Count > 0) DoReplace();

            var buffer = System.IO.File.ReadAllBytes(SourcePath);

            var msg = new FileTransferMessage()
                {
                    Buffer = buffer,
                    Length = buffer.Length,
                    FileLocation = TargetPath
                };

            var uploader = new DoPublishUpload<FileTransferMessage>();
            uploader.OnCompleted += (o, e) =>
            {
                ar_callback(this);
            };
            uploader.OnProgressChanged += (o, e) => { };
            uploader.Go("0099", msg);
        }
    }
}
